package com.thinkingstar.iads.cs.sys.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.servlet.ShiroFilter;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Chain;
import org.nutz.integration.shiro.SimpleShiroToken;
import org.nutz.lang.Strings;
import org.nutz.mvc.View;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.By;
import org.nutz.mvc.annotation.Param;
import com.thinkingstar.iads.common.config.BaseModule;
import com.thinkingstar.iads.common.filter.GlobalsFilter;
import com.thinkingstar.iads.common.utils.CommonDateUtil;
import com.thinkingstar.iads.cs.sys.entity.SysSafeconfig;
import com.thinkingstar.iads.cs.sys.entity.SysUser;
import com.thinkingstar.iads.datacenter.entity.dao.DaoDcProjectSysUser;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.Ok;
import org.nutz.ioc.loader.annotation.Inject;
import javax.servlet.http.HttpServletRequest;
import org.nutz.ioc.loader.annotation.IocBean;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.commons.lang3.math.NumberUtils;
import org.nutz.mvc.view.ServerRedirectView;

import java.io.IOException;
import java.util.List;

/**
 * 登录类
 * @author Administrator
 *
 */
@IocBean@Filters({@By(type = GlobalsFilter.class)})

public class LoginModule extends BaseModule {

    private static final String PATH = "beetl:/sys/";

    @Inject
    protected Dao dao;

    @Inject
    protected DaoDcProjectSysUser daoDcProjectSysUser;

    @At({"/","/login"})
    @Ok(PATH+"login.html")
    public void login(HttpServletRequest req, HttpServletResponse resp) {

    }

    @At("/ddLogin")
    @Ok(">>:/login")
    public View ddLogin(@Param("loginname") String loginname, HttpSession session, HttpServletRequest req) {
        List<SysUser> list = daoCtl.list(dao, SysUser.class,Cnd.where("loginname", "=", loginname));
        if(null!=list && list.size()>0){
            SysUser user = list.get(0);
            //有此用户
            SimpleShiroToken token = new SimpleShiroToken(loginname);
            //token.setRememberMe(true);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);

            user.setLogincount(user.getLogincount() + 1);
            user.setLogintime(CommonDateUtil.getDateTime());
            user.setLogintype(0);
            daoCtl.update(dao, user);
//        将用户的资源角色专业信息放入session
            user.setRolelist(daoDcProjectSysUser.getUserRoleByUserId(user.getId()));
            user.setMajorList(daoDcProjectSysUser.getMajorByUserId(user.getId()));
            user.setReslist(daoDcProjectSysUser.getResourceIdByUserId(user.getId()));
//            user.setSysrole(SecurityUtils.getSubject().hasRole("admin"));//用户是否拥有系统管理员权限
            user.setSysrole(daoDcProjectSysUser.is_admin(user.getId()));
            subject.getSession().setAttribute("userSession", user);
            subject.getSession().setAttribute("validate", "");
            subject.getSession().removeAttribute("errorlogincount");
            subject.getSession().setTimeout(-1000L);//设置永不过期
            System.out.println("当前用户登录状态："+subject.isAuthenticated());
            ServerRedirectView view = new ServerRedirectView(
                    "resource/index");
            return view;
        } else {
            ServerRedirectView view = new ServerRedirectView(
                    "resource/index");
            return view;
        }
    }


    @At("/doLogin")
    @Ok("json")
    public String login(@Param("loginname") String loginname,
                        @Param("password") String password,
                        @Param("verifcode") String verifcode, HttpSession session,
                        HttpServletRequest req) {
        if (Strings.isBlank(loginname) || Strings.isBlank(password))
            return "用户名及密码不能为空！";
        String vcode = Strings.sNull(session
                .getAttribute("ValidateCode"));
        if (!vcode.equals(verifcode))
            return "验证码不正确！";
//        SysUser user = daoCtl.detailByName(dao, SysUser.class, "loginname", loginname);
        /**
         * 权限入口
         */
        SimpleShiroToken token = new SimpleShiroToken(loginname);
        //token.setRememberMe(true);
        Subject subject = SecurityUtils.getSubject();

        try {
            subject.login(token);
            SysUser user = (SysUser)subject.getPrincipal();
            String hashedPasswordBase64 = new Sha256Hash(password, user.getSalt(), 1024).toBase64();
            if (!hashedPasswordBase64.equals(user.getPassword())) {
                int all = 5;
                int count = NumberUtils.toInt(Strings.sNull(session
                        .getAttribute("errorlogincount")), 0);
                if (count > 4) {
                    if (user.getState() == 0)
                        daoCtl.update(dao, SysUser.class, Chain.make("state", 1),
                                Cnd.where("loginname", "=", user.getLoginname()));
                    session.removeAttribute("errorlogincount");
                    return "密码输错次数过多，用户已被禁用！";
                } else {
                    session.setAttribute("errorlogincount", count + 1);
                }
                all = all - count;
                return "密码不正确，你还有" + all + "次机会！";
            }
            user.setLogincount(user.getLogincount() + 1);
            //        user.setLoginip(ip);
            user.setLogintime(CommonDateUtil.getDateTime());
            user.setLogintype(0);
            daoCtl.update(dao, user);
//        将用户的资源角色专业信息放入session
            user.setRolelist(daoDcProjectSysUser.getUserRoleByUserId(user.getId()));
            user.setMajorList(daoDcProjectSysUser.getMajorByUserId(user.getId()));
            user.setReslist(daoDcProjectSysUser.getResourceIdByUserId(user.getId()));
//            user.setSysrole(SecurityUtils.getSubject().hasRole("admin"));//用户是否拥有系统管理员权限
            user.setSysrole(daoDcProjectSysUser.is_admin(user.getId()));
            subject.getSession().setAttribute("userSession", user);
            subject.getSession().setAttribute("validate", "");
            subject.getSession().removeAttribute("errorlogincount");
            System.out.println("当前用户登录状态："+subject.isAuthenticated());

        } catch (UnknownAccountException uae) {
            return "用户帐号或密码不正确";

        } catch (IncorrectCredentialsException ice) {
            return "用户帐号或密码不正确";

        } catch (LockedAccountException lae) {
            return "用户帐号被锁定不可用";

        } catch (AuthenticationException ae) {
            return "登录失败!";
        }
        return "true";
    }

    /**
     * 登出方法
     * @param session
     */
    @At
    @Ok(">>:/login")
    //浏览器重定向
    public void logout(HttpSession session) {
        SecurityUtils.getSubject().logout();
    }

    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("PRoxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    @At
    //@Ok("vm:template.front.website")
    public void website(HttpServletRequest req) {
    }

    @At
    //@Ok("vm:template.front.report")
    public void report(HttpServletRequest req) {
    }


}
